<?php
abstract class BaseModel {

  //abstract function, return an array which key is DB column name and value is object property name
  abstract protected function getColumnPropertyMapper();

  public function __get($property) {
    if (isset($this->$property)) {
      return ($this->$property);
    } else {
      return NULL;
    }
  }

  public function __set($property, $value) {
    $this->$property = $value;
  }

  public function toArray($obj = false) {
    $obj = $obj ? $obj : $this;
    $propertyList = get_object_vars($obj);
    $arr = array();
    foreach ($propertyList as $key => $val) {
      $val = (is_array($val)) || is_object($val) ? toArray($val) : $val;
      $arr[$key] = $val;
    }
    return $arr;
  }

  public function toDBRawDataArray($withEmptyColumn = false) {
    $propertyList = get_object_vars($this);
    $arr = array();
    $mapper = $this->getColumnPropertyMapper();
    foreach ($mapper as $col => $property) {
      if (array_key_exists($property,$propertyList)) {
        $arr[$col] = $this->$property;
      } else if ($withEmptyColumn) {
        $arr[$col] = '';
      }
    }
    return $arr;
  }

  public function fillModel($row) {
    if (is_array($row)) {
      $mapper = $this->getColumnPropertyMapper();
      foreach($row as $k => $v) {
        if (array_key_exists($k,$mapper)) {
          $property = $mapper[$k];
          $this->$property = $v;
        }
      }
    }
  }

  protected function propertyToColumn($targetProperty) {
    $mapper = $this->getColumnPropertyMapper();
    foreach($mapper as $col => $property) {
      if ($targetProperty == $property)
        return $col;
    }
    return null;
  }

  protected function columnToProperty($targetColumn) {
    $mapper = $this->getColumnPropertyMapper();
    return array_key_exists($targetColumn,$mapper) ? $mapper[$targetColumn] : null;
  }

    protected static function filterArray($v){
        if(is_array($v)){
            $tmp = array();
            foreach($v as $k=>$va){
                if($v[$k]===NULL){
                    $tmp[$k] = '';
                }else{
                    $tmp[$k] =  is_string($v[$k])?$v[$k]:(string)$v[$k];
                }
            }
            return $tmp;
        }else{
            if($v){
                return  is_string($v)?$v:(string)$v;
            }else{
                return '';
            }
        }
    }
}
?>